package com.lianlianche.arch.jetpack

import android.app.Application
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.TimeUnit

/**
 * <pre>
 *     @author : Mid
 *     e-mail  : boyce903301689@gmail.com
 *     time    : 2019/7/18
 *     desc    : App基础组件配置类
 *               1.对基础的组件类进行相关配置并且提供对象引用
 *     version : 1.0
 * </pre>
 */
class AppComponent private constructor(builder: Builder){

    private val TIME_OUT = 10.toLong()

    //Application
    val application = builder.application!!

    //Gson
    val gson: Gson = builder.gsonBuilder?.create() ?: GsonBuilder().create()


    //okHttpClient
    val okHttpClient: OkHttpClient = builder.okHttpBuilder?.build() ?: OkHttpClient.Builder().apply {
        connectTimeout(TIME_OUT, TimeUnit.SECONDS)
        readTimeout(TIME_OUT, TimeUnit.SECONDS)
    }.build()


    //Retrofit
    private val retrofit: Retrofit = builder.retrofitBuilder?.apply {
        client(okHttpClient)
        addConverterFactory(GsonConverterFactory.create(gson))

    }?.build() ?: Retrofit.Builder().apply {
        baseUrl("")
        client(okHttpClient)
        addConverterFactory(GsonConverterFactory.create(gson))

    }.build()

    //NetWorkResource
    val netWorkResource = NetWorkResource(retrofit)


    class Builder {
        var application: Application? = null
        var okHttpBuilder: OkHttpClient.Builder? = null
        var retrofitBuilder: Retrofit.Builder? = null
        var gsonBuilder: GsonBuilder? = null

        fun build(): AppComponent {
            if (application == null) {
                throw IllegalArgumentException("Application cannot be null")
            }
            return AppComponent(this)
        }
    }

    companion object {

        @Volatile private var instance: AppComponent? = null

        fun init(builder: Builder) {
            if (instance != null) {
                throw IllegalArgumentException("AppComponent cannot be created repeatedly")
            }
            instance ?: synchronized(this) {
                instance ?: builder.build().also { instance = it }
            }
        }

        fun application() = instance?.application ?: throw NullPointerException("Application Not Created")

        fun okHttpClient() = instance?.okHttpClient ?: throw NullPointerException("OkHttpClient Not Created")

        fun gson() = instance?.gson ?: throw NullPointerException("Gson Not Created")

//        fun retrofit() = instance?.retrofit ?: throw NullPointerException("Retrofit Not Created")

        fun netWorkResource() = instance?.netWorkResource ?: throw NullPointerException("NetWorkResource Not Created")
    }
}